// Package usecase defines all the interfaces for a Micro-service application.
// It is the entry point for the application's business logic. It is a top level package for a Micro-service application.
// This top level package only defines interface, the concrete implementations are defined in sub-package of it.
// It only depends on model package. No other package should dependent on it except cmd.

// If transaction is supported, the transaction boundary should be defined in this package.
// A suffix-"WithTx" can be added to the name of a transaction function to distinguish it from a non-transaction one.

// The use cases in this application are not real world use cases, and they are created to illustrate the project layout.
// You should replace them with your real use case.

package usecase

import (
	"github.com/jfeng45/servicetmpl/model"
)

// RegistrationUseCaseInterface is for users to register themselves to an application. It has registration related functions.
// ModifyAndUnregisterWithTx() is the one supporting transaction, the other are not.
type RegistrationUseCaseInterface interface {
	// RegisterUser register a user to an application, basically save it to a database. The returned resultUser that has
	// a Id ( auto generated by database) after persisted
	RegisterUser(user *model.User) (resultUser *model.User, err error)
	// UnregisterUser unregister a user from an application by user name, basically removing it from a database.
	UnregisterUser(username string) error
	// ModifyUser change user information based on the User.Id passed in.
	ModifyUser(user *model.User) error
	// ModifyAndUnregister change user information and then unregister the user based on the User.Id passed in.
	// It is created to illustrate transaction, no real use.
	ModifyAndUnregister(user *model.User) error
	// ModifyAndUnregisterWithTx change user information and then unregister the user based on the User.Id passed in.
	// It supports transaction
	// It is created to illustrate transaction, no real use.
	ModifyAndUnregisterWithTx(user *model.User) error
	// EnableTx enable transaction support on use case. Need to be included for each use case needs transaction
	// It replaces the underline database handler to sql.Tx for each data service that used by this use case
	EnableTxer
}

// ListUserUseCaseInterface handles different ways to retrieve user information
type ListUserUseCaseInterface interface {
	// ListUser retrieves all users as an array of user
	ListUser() ([]model.User, error)
	// Find retrieves a user based on a user's id
	Find(id int) (*model.User, error)
}

// ListCourseUseCaseInterface handles different ways to retrieve user information
// It is created to show POC of courseDatServiceFactory, no real use
// Only SQL database is implemented for this use case, not couchdb.
type ListCourseUseCaseInterface interface {
	// ListCourse retrieves all courses as an array of course
	ListCourse() ([]model.Course, error)
}

// EnableTxer is the transaction interface for use case layer
type EnableTxer interface {
	EnableTx()
}
